home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 August: Tool Chest / Dev.CD Aug 95 TC / Dev.CD Aug 95 TC.toast / Sample Code / Snippets / Toolbox / Modeless Dialog Sample / Application.c next >
Encoding:
C/C++ Source or Header  |  1994-02-23  |  9.0 KB  |  383 lines  |  [TEXT/MPS ]

  1.  
  2. #include "SampleHeader.h"
  3.  
  4. /* In the 68K world, this is provided for you as part of your A5 world, but */
  5. /* on the PowerPC, you have to explicitly include it.                        */
  6. #ifdef __powerc
  7. QDGlobals qd;
  8. #endif
  9.  
  10. /* Two globals.  One always tells me whether I'm in the background or not    */
  11. /* (maintained in the Suspend/Resume event handler in MainEventLoop()), and    */
  12. /* another that allows me to cleanly drop out of my main event loop from     */
  13. /* anywhere.  Sure ExitToShell() works, too, but I like to exit in only one    */
  14. /* way, and this global allows me to do that.                                */
  15. Boolean gDone;
  16. Boolean gInBackground;
  17.  
  18. /*-------------------------------------------------------------------------------------*/
  19.  
  20. void main()
  21. {
  22.  
  23.     InitApplication();
  24.     PreEventLoop();
  25.     MainEventLoop();
  26. }
  27.  
  28.  
  29. /*-------------------------------------------------------------------------------------*/
  30. /*
  31.     InitApplication - initializes the toolbox, my globals, and my menu bar.
  32. */
  33. void InitApplication()
  34. {
  35.     Handle theMenu;
  36.  
  37.     // Toolbox initialization
  38.     MaxApplZone();
  39.     InitGraf(&qd.thePort);
  40.     InitFonts();
  41.     InitWindows();
  42.     InitMenus();
  43.     TEInit();
  44.     InitDialogs(nil);
  45.     InitCursor();
  46.     FlushEvents(0,everyEvent);
  47.     
  48.     // Application initialization
  49.     gDone = false;
  50.     gInBackground = false;
  51.     
  52.     theMenu = GetNewMBar(kMenuBarResID);
  53.     if ( theMenu != nil )
  54.     {
  55.         SetMenuBar(theMenu);
  56.         AddResMenu(GetMHandle(kAppleMenu), 'DRVR');
  57.         DrawMenuBar();
  58.     }
  59.     else
  60.         /* If the menu stuff failed, something just ain't    */
  61.         /* right (most likely some resources are missing).    */
  62.         gDone = true;
  63.  
  64. }
  65.  
  66.  
  67. /*-------------------------------------------------------------------------------------*/
  68. /*
  69.     DoAboutBox - I just have an Alert dialog box set up in my resources for this.
  70. */
  71. void DoAboutBox()
  72. {
  73.     (void) Alert(kAboutBoxDITLID, nil);
  74. }
  75.  
  76.  
  77. /*-------------------------------------------------------------------------------------*/
  78. /*
  79.     MainEventLoop - handles all events for this application.  Note that the first
  80.     thing done with an event is to check if it belongs to a dialog, and if so the
  81.     event is passed to DoDialogEvent() which handles all dialog events except
  82.     null events.  To check if it's a dialog event, the IsDialogEvent routine is
  83.     called which checks to see if the frontmost window is a dialog and if the
  84.     event is not an update,  a mousedown or an activate for another window.  Note
  85.     that null events are all passed to DoDialogNullEvent, which is needed to keep
  86.     the editText cursor blinking..
  87.  
  88. */
  89. void MainEventLoop()
  90. {
  91.     EventRecord        theEvent;
  92.     WindowPtr        thisWindow;
  93.     short            clickArea;
  94.     Rect            screenRect;
  95.     long            menuResult;
  96.     char            charCode;
  97.  
  98.     while ( !gDone )
  99.     {
  100.         if ( WaitNextEvent(everyEvent, &theEvent, 0, nil) )
  101.         {
  102.             if ( IsDialogEvent(&theEvent) == true )
  103.             {
  104.                 DoDialogEvent(&theEvent);
  105.                 continue;
  106.             }
  107.  
  108.             switch (theEvent.what)
  109.             {
  110.                 case mouseDown:
  111.                     clickArea = FindWindow(theEvent.where, &thisWindow);
  112.                     
  113.                     switch ( clickArea )
  114.                     {
  115.                         case inDrag:
  116.                             screenRect = (**GetGrayRgn()).rgnBBox;
  117.                             DragWindow(thisWindow, theEvent.where, &screenRect);
  118.                             break;
  119.                         case inContent:
  120.                             if ( thisWindow != FrontWindow() )
  121.                                 SelectWindow(thisWindow);
  122.                             break;
  123.                         case inGoAway:
  124.                             if ( TrackGoAway(thisWindow, theEvent.where) == true )
  125.                             {
  126.                                 if ( ((WindowRecord *)thisWindow)->windowKind == dialogKind )
  127.                                     DisposeDialog(thisWindow);
  128.                                 else
  129.                                     gDone = true;
  130.                             }
  131.                             break;
  132.                         case inMenuBar:
  133.                             AdjustMenus();
  134.                             menuResult = MenuSelect(theEvent.where);
  135.                             if ( (menuResult  >> 16) != 0 )
  136.                                 (void) MenuCommand(menuResult);
  137.                             break;
  138.                     }
  139.  
  140.                     break;
  141.                 case keyDown:
  142.                     charCode = theEvent.message & charCodeMask;
  143.  
  144.                     if ( (theEvent.modifiers & cmdKey) != 0 ) 
  145.                     {    
  146.                         AdjustMenus();
  147.                         menuResult = MenuKey(charCode);
  148.                 
  149.                         if ( (menuResult  >> 16) != 0 )
  150.                             (void) MenuCommand(menuResult);
  151.                             
  152.                     } 
  153.                     break;
  154.                 case updateEvt:
  155.                     thisWindow = (WindowPtr)theEvent.message;    
  156.                     DoUpdate(thisWindow);
  157.                 
  158.                     break;
  159.                 case app4Evt: 
  160.                     /* Make sure the SIZE resource reflects that suspend evts are accepted.*/
  161.                     if ( theEvent.message & 0x01000000 )         /* Suspend or resume? */
  162.                     {
  163.                         if ( theEvent.message & 0x00000001 )/* Is it a resume event? */
  164.                         {
  165.                             gInBackground = false;
  166.                             SetCursor(&qd.arrow);
  167.                         }
  168.                         else                                 /* It's a suspend event */
  169.                             gInBackground = true;
  170.  
  171.                     }
  172.                     break;
  173.             }
  174.         }
  175.         else
  176.             DoDialogNullEvent(&theEvent);
  177.     }
  178. }
  179.  
  180.  
  181.  
  182. /*-------------------------------------------------------------------------------------*/
  183. /*
  184.     MenuCommand - called in response to keydowns in both my dialog event handler and
  185.     the main event loop.  Note that because of AdjustMenus(), the edit keys will only
  186.     be hit if the dialog is the frontmost window, which is what we want.
  187.  
  188. */
  189. Boolean MenuCommand(long whaHappened)
  190. {
  191.     short        menuID, menuItem;
  192.     Boolean     performedEdit = false;
  193.     DialogPtr    theDialog;
  194.     
  195.     menuID = (whaHappened >> 16);
  196.     menuItem = (whaHappened & 0xFFFF);
  197.     
  198.     switch ( menuID )
  199.     {
  200.         case kAppleMenu:
  201.             HiliteMenu(kAppleMenu);
  202.             if ( menuItem == 1)
  203.                 DoAboutBox();
  204.             break;
  205.  
  206.         case kFileMenu:
  207.             HiliteMenu(kFileMenu);
  208.             switch ( menuItem )
  209.             {
  210.                 case kNewItem:
  211.                     CreateModelessDialog();
  212.                     break;
  213.                 case kQuitItem:
  214.                     gDone = true;
  215.                     break;
  216.             }
  217.             break;
  218.         case kEditMenu:
  219.             // This thing should be a dialog, because the menu items are
  220.             // disabled unless a modeless dialog is frontmost.
  221.             theDialog = (DialogPtr)FrontWindow();
  222.             
  223.             if ( theDialog != nil )
  224.             {
  225.                 HiliteMenu(kEditMenu);            
  226.                 switch ( menuItem )
  227.                 {
  228.                     case kCutItem:
  229.                         DoCut(theDialog);
  230.                         performedEdit = true;
  231.                         break;
  232.                     case kCopyItem:
  233.                         DoCopy(theDialog);
  234.                         performedEdit = true;
  235.                         break;
  236.                     case kPasteItem:
  237.                         DoPaste(theDialog);
  238.                         performedEdit = true;
  239.                         break;
  240.                     case kClearItem:
  241.                         DoClear(theDialog);
  242.                         performedEdit = true;
  243.                         break;
  244.                 }
  245.             }
  246.             break;
  247.     }
  248.     HiliteMenu(0);
  249.     return performedEdit;
  250. }
  251.  
  252.  
  253.  
  254.  
  255. /*-------------------------------------------------------------------------------------*/
  256. /*
  257.     DrawIt - I've included a normal window in this application to show the difference
  258.     between handling events for a dialog and a normal window.  This just draws some
  259.     text into the normal window.
  260.  
  261. */
  262. void DrawIt(WindowPtr win)
  263. {
  264.     short         origFont, origSize;
  265.     
  266.     origFont = win->txFont;
  267.     origSize = win->txSize;
  268.     TextFont(geneva);
  269.     TextSize(48);
  270.  
  271.     ForeColor(redColor);
  272.     PaintRect(&(*win).portRect);
  273.     ForeColor(blackColor);
  274.  
  275.     MoveTo(10, win->portRect.bottom - 10);
  276.     DrawString((StringPtr)"\pModeless Sample");
  277.  
  278.     TextFont(origFont);
  279.     TextSize(origSize);
  280. }
  281.  
  282.  
  283. /*-------------------------------------------------------------------------------------*/
  284. /*
  285.     DrawWindowContent - called by DeviceLoop in the main event loop.  In response to 
  286.     update events.
  287.     
  288.     Since I don't do anything different for different depths, grayscale, etc, I just 
  289.     ignore those parameters, but you don't have to.
  290.  
  291. */
  292. pascal void DrawWindowContent(short pixelDepth, short dFlags, GDHandle theDevice, long theWin)
  293. {
  294. #pragma unused (pixelDepth, dFlags, theDevice)
  295.     GrafPtr        savePort;
  296.  
  297.     GetPort(&savePort);
  298.     SetPort((GrafPtr)theWin);
  299.  
  300.     DrawIt((WindowPtr)theWin);
  301.  
  302.     SetPort(savePort);
  303. }
  304.  
  305.  
  306. /*-------------------------------------------------------------------------------------*/
  307. /*
  308.     CreateNewWindow - called in PreEventLoop to create the normal non-dialog window.
  309.  
  310. */
  311. void CreateNewWindow(void)
  312. {
  313.     Rect winDimension;
  314.     
  315.     SetRect(&winDimension, 60, 60, 475, 120);
  316.     (void)NewCWindow(0L, &winDimension, (StringPtr)"\pSample", true, noGrowDocProc,
  317.                             (WindowPtr)-1L, true, 0L);
  318. }
  319.  
  320.  
  321.  
  322. /*-------------------------------------------------------------------------------------*/
  323. /*
  324.     DoUpdate - called in the main event loop.
  325.  
  326. */
  327. void DoUpdate(WindowPtr thisWindow)
  328. {
  329.     static DeviceLoopDrawingUPP    procForDeviceLoop = nil;
  330.  
  331.     SetPort(thisWindow);
  332.  
  333.     if ( procForDeviceLoop == nil )
  334.         procForDeviceLoop = NewDeviceLoopDrawingProc(DrawWindowContent);    
  335.     
  336.     BeginUpdate(thisWindow);
  337.     DeviceLoop(thisWindow->visRgn, procForDeviceLoop, (long)thisWindow, singleDevices);
  338.     EndUpdate(thisWindow);
  339. }
  340.  
  341.  
  342. /*-------------------------------------------------------------------------------------*/
  343.  
  344. void PreEventLoop(void)
  345. {
  346.     CreateNewWindow();
  347.     CreateModelessDialog();
  348. }
  349.  
  350.  
  351. /*-------------------------------------------------------------------------------------*/
  352.  
  353. void PostEventLoop(void)
  354. {
  355. }
  356.  
  357.  
  358. /*-------------------------------------------------------------------------------------*/
  359. /*
  360.     AdjustMenus - called in whenever command-keys are pressed, or if the menu bar is
  361.     hit with the mouse, so the menus are adjusted only right before they're accessed.
  362. */
  363. void AdjustMenus(void)
  364. {
  365.     MenuHandle    theFuncsMenu = GetMenu(kEditMenu);
  366.     WindowPtr    theWindow = FrontWindow();
  367.     
  368.     if ( ((WindowRecord *)theWindow)->windowKind != dialogKind )
  369.     {
  370.         DisableItem(theFuncsMenu, kCutItem);
  371.         DisableItem(theFuncsMenu, kCopyItem);
  372.         DisableItem(theFuncsMenu, kPasteItem);
  373.         DisableItem(theFuncsMenu, kClearItem);
  374.     }
  375.     else
  376.     {
  377.         EnableItem(theFuncsMenu, kCutItem);
  378.         EnableItem(theFuncsMenu, kCopyItem);
  379.         EnableItem(theFuncsMenu, kPasteItem);
  380.         EnableItem(theFuncsMenu, kClearItem);
  381.     }
  382. }
  383.